// Copyright 2011 Google Inc. All rights reserved.
// Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file.

/*
The mail package provides the means of sending email from an
App Engine application.

Example:
	msg := &mail.Message{
		Sender:  "romeo@montague.com",
		To:      []string{"Juliet <juliet@capulet.org>"},
		Subject: "See you tonight",
		Body:    "Don't forget our plans. Hark, 'til later.",
	}
	if err := mail.Send(c, msg); err != nil {
		c.Logf("Alas, my user, the email failed to sendeth: %v", err)
	}
*/
package myappenginemail

import (
	"os"
	"appengine"
//    "template"
    "fmt"
	"strings"
	"bytes"
	"bufio"
	"mime"
	"mime/multipart"
	//"mail"
	"net/textproto"
	"io/ioutil"
	"io"
	"encoding/base64"
)


type MyReader struct {
	data *bytes.Buffer
	last byte
}

func NewMyReader( buffer []byte) (*MyReader) {
	return &MyReader{ bytes.NewBuffer(buffer), 0}
}

func (r *MyReader) Read(p []byte) (n int, err os.Error) {
 	c, err := r.data.ReadByte()
	if err != nil {
		return 0, err
	}
	if c == '\n' && r.last != '\r' {
		p[0] = '\r'
		p[1] = c
		r.last = c
		return 2, nil
	}
	r.last = c
 	p[0] = c
	return 1, nil
}


type MyMail struct {
	content []byte
	tp *textproto.Reader
	header map[string][]string
	mpr multipart.Reader
}

func NewMyMail( in io.Reader) (*MyMail, os.Error) {
 	content, err := ioutil.ReadAll( in)
    if err != nil {
        return nil, err
  	}
  	fmt.Println( string(content))
  	return &MyMail{ content:content}, nil
}

func (myMail *MyMail) NewReader( ) io.Reader {
	return bytes.NewBuffer( myMail.content)	
}

func (myMail *MyMail) Header( key string) []string {
	if myMail.tp == nil {
		myMail.readMime()
	}
	return myMail.header[key]
}

func (myMail *MyMail) MediaType( ) (mediatype string, params map[string]string) {
	v := myMail.Header("Content-Type")[0]
	return mime.ParseMediaType(v)
}

func (myMail *MyMail) NextPart(c appengine.Context) (partHeader *textproto.MIMEHeader, partBody []byte, err os.Error) {
	if myMail.tp == nil {
		myMail.readMime()
	}
	if myMail.mpr == nil {
		_, params := myMail.MediaType()
		boundary := params["boundary"]
		myMail.mpr = multipart.NewReader(myMail.tp.R, boundary)
	}
	part, err := myMail.mpr.NextPart()
	if err != nil {
		return
	}
	partHeader = &part.Header

	if partHeader.Get("Content-Transfer-Encoding") == "base64" {
		r := base64.NewDecoder( base64.StdEncoding, part) 
		partBody, err = ioutil.ReadAll( r)
		c.Debugf( "partBody-base64:<<%v>>", string(partBody))
		str2 := string(partBody)
		str2 = strings.Replace(str2, "\xE7", "ç", -1)
		str2 = strings.Replace(str2, "\xF1", "ñ", -1)
		str2 = strings.Replace(str2, "\xE1", "á", -1)
		str2 = strings.Replace(str2, "\xE9", "é", -1)
		str2 = strings.Replace(str2, "\xED", "í", -1)
		str2 = strings.Replace(str2, "\xF3", "ó", -1)
		str2 = strings.Replace(str2, "\xFA", "ú", -1)
		str2 = strings.Replace(str2, "\xD1", "Ñ", -1)
		str2 = strings.Replace(str2, "\xC7", "Ç", -1)
		str2 = strings.Replace(str2, "\xC1", "Á", -1)
		str2 = strings.Replace(str2, "\xC9", "É", -1)
		str2 = strings.Replace(str2, "\xCD", "Í", -1)
		str2 = strings.Replace(str2, "\xD3", "Ó", -1)
		str2 = strings.Replace(str2, "\xDA", "Ú", -1) 
		partBody = []uint8(str2)
		return
	}	
	partBody, err = ioutil.ReadAll( part)
	c.Debugf( "partBody-text:<<%v>>", string(partBody))
	body := string(partBody)
	body = strings.Replace( body, "=E1", "á", -1)
	body = strings.Replace( body, "=E9", "é", -1)
	body = strings.Replace( body, "=ED", "í", -1)
	body = strings.Replace( body, "=F3", "ó", -1)
	body = strings.Replace( body, "=F3", "ú", -1)
	body = strings.Replace( body, "=F1", "ñ", -1)

	body = strings.Replace(body, "=D1", "Ñ", -1)
	body = strings.Replace(body, "=C7", "Ç", -1)
	body = strings.Replace(body, "=C1", "Á", -1)
	body = strings.Replace(body, "=C9", "É", -1)
	body = strings.Replace(body, "=CD", "Í", -1)
	body = strings.Replace(body, "=D3", "Ó", -1)
	body = strings.Replace(body, "=DA", "Ú", -1) 
	partBody = []uint8(body)
	return
}
   
func (myMail *MyMail) GetBody() (body []byte, err os.Error) {
	if myMail.tp == nil {
		err = myMail.readMime()
		if err != nil {
			return
		}
	}
	body, err = ioutil.ReadAll( myMail.tp.R)
	return
}
   
func (myMail *MyMail) readMime() (err os.Error) {
	b := NewMyReader( myMail.content)
	b2 := bufio.NewReader( b)
	myMail.tp = textproto.NewReader(b2)
	myMail.header, err = myMail.tp.ReadMIMEHeader()
	fmt.Printf("readedMime, %v\n",err)
	return
}




